﻿
//输入: 语法树 --> 中间语言指令序列
//每个指令的元素都用空格分隔(用+表示空格, 用&表示字符串连接)
//变量索引是 int 类型

namespace n_Deploy
{
using System;
using n_Code1;
using n_Config;
using n_ControlSence;
using n_ET;
using n_Expression;
using n_FunctionCodeList;
using n_FunctionList;
using n_LabelList;
using n_LabelNode;
using n_MemberType;
using n_Operation;
using n_Parse;
using n_ParseNet;
using n_VarList;
using n_VarType;
using n_WordList;
using n_CallList;
using n_CDebug;
using n_Param;
using n_Opti;

public static class Deploy
{
	//把语法树的根节点转化为中间语言指令序列
	public static void TurnToSupperASM()
	{
		FunctionIndex = 0;
		SenceNumber = 0;
		
		ChipIndex = 0;
		Config.SetChipIndex( ChipIndex );
		
		n_Param.Param.UserspaceOn = false;
		
		//清零标号列表
		LabelList.Clear();
		
		//清空函数代码列表
		FunctionCodeList.Clear();
		
		CallList.Clear();
		
		Parse.DealWith( ref UnitName, new Parse.MemberListHandle( 成员列表 ) );
		
		//优化
		Opti.Run();
	}
	
	static void 成员列表( int Index )
	{
		VarLevel = 1;
		for( int i = 1; i < ParseNet.NodeSet[ Index].Length; ++i ) {
			
			int index = int.Parse( ParseNet.NodeSet[ Index ][ i ] );
			
			//判断是否元件定义
			if( ParseNet.NodeSet[ index ][ 0 ] == ParseNet.Node.元件 ) {
				元件( index );
				continue;
			}
			//判断是否函数定义
			if( ParseNet.NodeSet[ index ][ 0 ] == ParseNet.Node.函数 ) {
				FunctionCodeList.SetFunctionIndex( FunctionIndex );
				函数( index );
				++FunctionIndex;
				continue;
			}
			//判断是否设置芯片
			if( ParseNet.NodeSet[ index ][ 0 ] ==ParseNet.Node.设置当前包 ) {
				++ChipIndex;
				Config.SetChipIndex( ChipIndex );
				continue;
			}
			//判断是否为设置编译参数
			if( ParseNet.NodeSet[ index ][ 0 ] ==ParseNet.Node.设置编译参数 ) {
				//获取参数信息
				int ParamIndex = int.Parse( ParseNet.NodeSet[ index ][ 2 ] );
				string param = WordList.GetWord( ParamIndex );
				if( param == Param.FUNCTION_USED ) {
					Param.function_used = true;
				}
				else if( param == Param.S_UserspaceOn ) {
					Param.UserspaceOn = true;
				}
				else if( param == Param.S_UserspaceOff ) {
					Param.UserspaceOn = false;
				}
				else {
					ET.WriteParseError( ParamIndex, "未知的编译参数: " + param );
				}
				continue;
			}
		}
	}
	
	static void 元件( int Index )
	{
		Parse.Unit( ref UnitName, Index, new Parse.MemberListHandle( 成员列表 ) );
	}
	
	static void 函数( int Index )
	{
		if( Param.function_used ) {
			Param.function_used = false;
			FunctionList.Get( FunctionIndex ).isUsed = true;
		}
		
		ExpLevel = 1;
		
		Expression.AddIns( Code1.函数名称 + " " + n_Config.Config.PreLabel.Function + FunctionIndex );
		
		//获取函数形参列表并检查是否和全局变量重名
		int index = int.Parse( ParseNet.NodeSet[ Index ][ 5 ] );
		if( index != -1 ) {
			for( int i = 1; i < ParseNet.NodeSet[ index ].Length; i += 2 ) {
				int j = int.Parse( ParseNet.NodeSet[ index ][ i ] );
				
				//获取变量名
				int VarNameIndex = int.Parse( ParseNet.NodeSet[ j ][ 2 ] );
				string Name = WordList.GetWord( VarNameIndex );
				
				//判断变量名是否有效
				if( VarList.GetDirectStaticIndex( UnitName + "." + Name ) != -1 ) {
					ET.WriteParseError( VarNameIndex, "函数形参名称无效, 已经定义了同名的全局变量: " + Name );
				}
			}
		}
		int SenceIndex = int.Parse( ParseNet.NodeSet[ Index ][ 8 ] );
		
		//判断是否中断函数
		if( FunctionList.Get( FunctionIndex ).InterType == MemberType.FunctionType.Interrupt ||
		    FunctionList.Get( FunctionIndex ).InterType == MemberType.FunctionType.Callback ) {
			
			if( !FunctionList.Get( FunctionIndex ).isFast ) {
				Expression.AddIns( Code1.保护现场 );
				if( Config.isProtectBaseCodeVarAtInt() ) {
					Expression.AddIns( Code1.保护接口实参 );
				}
				Expression.AddIns( Code1.设置堆栈 + " #" + FunctionIndex );
			}
			Expression.AddIns( Code1.转移形参 + " #" + FunctionIndex );
			
			语句列表( SenceIndex, -1 );
			//添加结尾标号用于返回指令 return(不能用RET直接返回)
			Expression.AddIns( Code1.标号 + " " + Config.PreLabel.FunctionInterEnd + FunctionIndex );
			
			if( !FunctionList.Get( FunctionIndex ).isFast ) {
				if( Config.isProtectBaseCodeVarAtInt() ) {
					Expression.AddIns( Code1.恢复接口实参 );
				}
				Expression.AddIns( Code1.恢复现场 );
			}
			
			Expression.AddIns( Code1.中断返回 );
		}
		else {
			语句列表( SenceIndex, -1 );
			//判断当前函数是否包含返回,不包含则自动添加
			//if( !Result.EndsWith( "返回\n" ) ) {
			Expression.AddIns( Code1.返回 );
			//}
		}
		//一定要添加空语句
		FunctionCodeList.AddCode( null );
	}
	
	public static void 语句列表( int Index, int ControlIndex )
	{
		for( int i = 1; i < ParseNet.NodeSet[ Index ].Length; ++i ) {
			语句( int.Parse( ParseNet.NodeSet[ Index ][ i ] ), ControlIndex );
		}
	}
	
	public static void 复合语句( int Index, int ControlIndex )
	{
		int ListIndex = int.Parse( ParseNet.NodeSet[ Index ][ 2 ] );
		if( ListIndex != -1 ) {
			语句列表( ListIndex, ControlIndex );
		}
	}
	
	public static void 语句( int Index, int ControlIndex )
	{
		string Head = ParseNet.NodeSet[ Index ][ 0 ];
		switch( Head ) {
			case ParseNet.Node.标号语句:			标号语句( Index ); return;
			case ParseNet.Node.表达式语句:		表达式语句( Index ); return;
			case ParseNet.Node.复合语句:			复合语句( Index, ControlIndex ); return;
			case ParseNet.Node.流程语句:			流程语句( Index, ControlIndex ); return;
			case ParseNet.Node.内嵌汇编:			内嵌汇编( Index ); return;
			case ParseNet.Node.系统标志:			系统标志( Index ); return;
			case ParseNet.Node.设置编译参数:		设置编译参数( Index ); return;
			//case ParseNet.Node.空语句:				return;
			default : 								控制语句( Index, ControlIndex ); return;
		}
	}
	
	public static void 流程语句( int Index, int ControlIndex )
	{
		int ExpIndex = int.Parse( ParseNet.NodeSet[ Index ][ 1 ] );
		string Head = ParseNet.NodeSet[ ExpIndex ][ 0 ];
		switch( Head ) {
			case ParseNet.Node.跳至控制:			goto语句( ExpIndex ); return;
			case ParseNet.Node.跳至开始控制:		start语句( ExpIndex, ControlIndex ); return;
			case ParseNet.Node.跳至结尾控制:		continue语句( ExpIndex, ControlIndex ); return;
			case ParseNet.Node.中断控制:			break语句( ExpIndex, ControlIndex ); return;
			case ParseNet.Node.返回控制:			return语句( ExpIndex ); return;
			default : 							无值表达式( ExpIndex ); return;
		}
	}
	
	static void continue语句( int Index, int ControlIndex )
	{
		if( ControlIndex == -1 ) {
			ET.WriteParseError( int.Parse( ParseNet.NodeSet[ Index ][ 1 ] ), "continue语句不能独立出现" );
		}
		跳转( Config.PreLabel.Continue + ControlIndex );
	}
	
	static void start语句( int Index, int ControlIndex )
	{
		if( ControlIndex == -1 ) {
			ET.WriteParseError( int.Parse( ParseNet.NodeSet[ Index ][ 1 ] ), "start语句不能独立出现" );
		}
		跳转( Config.PreLabel.Head + ControlIndex );
	}
	
	static void break语句( int Index, int ControlIndex )
	{
		if( ControlIndex == -1 ) {
			ET.WriteParseError( int.Parse( ParseNet.NodeSet[ Index ][ 1 ] ), "break语句不能独立出现" );
		}
		跳转( Config.PreLabel.End + ControlIndex );
	}
	
	static void goto语句( int Index )
	{
		跳转user( ParseNet.NodeSet[ Index ][ 2 ] );
	}
	
	static void return语句( int Index )
	{
		//判断return语句后面有没有表达式
		if( ParseNet.NodeSet[ Index ][ 2 ] == "-1" ) {
			
			//没有表达式但是当前函数要求返回一个类型,报错
			if( FunctionList.Get( FunctionIndex ).ReturnType != VarType.Void ) {
				ET.WriteParseError( int.Parse( ParseNet.NodeSet[ Index ][ 1 ] ), "return 语句缺少返回值" );
			}
		}
		else {
			string RetType = FunctionList.Get( FunctionIndex ).ReturnType;
			if( RetType == VarType.Void ) {
				ET.WriteParseError( int.Parse( ParseNet.NodeSet[ Index ][ 1 ] ),
					"return 语句所在的函数未定义返回值" );
			}
			int Name = Expression.表达式( int.Parse( ParseNet.NodeSet[ Index ][ 2 ] ) );
			if( Name == -1 ) {
				return;
			}
			Name = Expression.读取宏变量( Name );
			写系统量( FunctionIndex, Name );
		}
		if( FunctionList.Get( FunctionIndex ).InterType == MemberType.FunctionType.Interrupt ||
		    FunctionList.Get( FunctionIndex ).InterType == MemberType.FunctionType.Callback ) {
			跳转( Config.PreLabel.FunctionInterEnd + FunctionIndex );
		}
		else {
			Expression.AddIns( Code1.返回 );
		}
	}
	
	static void 标号语句( int Index )
	{
		string Name = WordList.GetWord( int.Parse( ParseNet.NodeSet[ Index ][ 1 ] ) );
		
		//这里修改了标签的定义,同一个函数中不允许出现同名的标签
		//string LabelName = "label_" + ParseNet.NodeSet[ Index ][ 1 ];
		string LabelName = Config.PreLabel.Label + FunctionIndex + "_" + Name;
		
		if( LabelList.isExist( Name, FunctionIndex ) ) {
			ET.WriteParseError( int.Parse( ParseNet.NodeSet[ Index ][ 1 ] ), "标号已经定义: " + Name );
			return;
		}
		LabelNode v = new LabelNode( Name, LabelName, VarLevel, FunctionIndex );
		LabelList.Add( v );
		Expression.AddIns( Code1.标号 + " " + LabelName );
	}
	
	static void 表达式语句( int Index )
	{
		int ExpIndex = int.Parse( ParseNet.NodeSet[ Index ][ 1 ] );
		ExpLevel = 0;
		
		int VarIndex = Expression.表达式( ExpIndex );
		if( VarIndex == -1 ) {
			return;
		}
		string Rtype = VarList.Get( VarIndex ).Type;
		string Name = VarList.Get( VarIndex ).Name;
		if( Rtype == VarType.Void ) {
			return;
		}
		//到这里说明是没有使用的变量结果,提示错误
		ET.WriteParseError( VarList.Get( VarIndex ).Location, "表达式的值未被使用,类型: " + Rtype );
	}
	
	public static void 无值表达式( int Index )
	{
		ExpLevel = 0;
		int Name = Expression.表达式( Index );
		if( Name == -1 ) {
			return;
		}
		if( VarList.Get( Name ).Type != VarType.Void ) {
			ET.WriteParseError( VarList.Get( Name ).Location, "表达式返回类型: " + VarList.Get( Name ).Type );
		}
	}
	
	static void 内嵌汇编( int Index )
	{
		int i = int.Parse( ParseNet.NodeSet[ Index ][ 2 ] );
		Expression.AddIns( Code1.内嵌汇编 + " " + i );
	}
	
	static void 系统标志( int Index )
	{
		int i = int.Parse( ParseNet.NodeSet[ Index ][ 2 ] );
		string Name = WordList.GetWord( i );
		Expression.AddIns( Code1.系统标志 + " " + Name );
		Debug.Deal( Name );
	}
	
	static void 设置编译参数( int Index )
	{
		//获取参数信息
		int ParamIndex = int.Parse( ParseNet.NodeSet[ Index ][ 2 ] );
		string param = WordList.GetWord( ParamIndex );
		if( param == Param.FUNCTION_USED ) {
			Param.function_used = true;
		}
		else if( param == Param.S_TestOn ) {
			Param.TestOn = true;
		}
		else if( param == Param.S_TestOff ) {
			Param.TestOn = false;
		}
		else {
			ET.WriteParseError( ParamIndex, "未知的编译参数: " + param );
		}
	}
	
	static void 控制语句( int Index, int ControlIndex )
	{
		ControlSence.控制语句( Index, ControlIndex );
	}
	
	static void 写系统量( int FunctionIndex, int VarIndex )
	{
		string ReturnType = FunctionList.Get( FunctionIndex ).ReturnType;
		VarIndex = Expression.读取方法( VarIndex );
		if( VarIndex == -1 ) {
			return;
		}
		string VarType = VarList.Get( VarIndex ).Type;
		if( VarType.IndexOf( ',' ) != -1 ) {
			VarType = Operation.GetDoubleVarType( VarType, ReturnType );
			VarList.Get( VarIndex ).Type = VarType;
		}
		if( ReturnType != VarType ) {
			VarIndex = Expression.隐式转换( ReturnType, VarIndex, VarType );
			if( VarIndex == -1 ) {
				return;
			}
		}
//				//判断形参的传递方式
//				if( VarType.isBase( FuncVarType ) ) {
//					j = 读取方法( j );
//						if( j == -1 ) {
//						return -1;
//					}
//					string Type2 = VarList.Get( j ).Type;
//					if( Type2.IndexOf( ',' ) != -1 ) {
//						Type2 = Operation.GetDoubleVarType( Type2, FuncVarType );
//						VarList.Get( j ).Type = Type2;
//					}
//					if( Type2 != FuncVarType ) {
//						j = Expression.隐式转换( FuncVarType, j, Type2 );
//						if( j == -1 ) {
//							return -1;
//						}
//						Type2 = FuncVarType;
//					}
//				}
//				else {
//					string jType = VarList.Get( j ).Type;
//					if( VarType.isBase( jType ) ) {
//						VarNode mv = new VarNode();
//						mv.SetTempValue( VarType.AddSysRefer( jType ), Deploy.VarLevel, VarList.Get( j ).Location );
//						int RetIndex = VarList.Add( mv );
//						AddIns( Code1.读取地址 + " " + RetIndex + " #" + j );
//						j = RetIndex;
//					}
//					else if( VarType.isSysReferForRefer( jType ) ) {
//						j = 读接口( j );
//					}
//				}
		
		
		Expression.AddIns( Code1.写系统量 + " # " + VarIndex );
	}
	
	//系统产生的跳转
	public static void 跳转( string Label )
	{
		Expression.AddIns( Code1.跳转 + " " + Label );
	}
	
	//用户的goto语句
	public static void 跳转user( string Label )
	{
		int Index = int.Parse( Label );
		string Name = WordList.GetWord( Index );
		
		//注意:这里不再判断标签是否定义,以便允许向下跳转
		Expression.AddIns( Code1.跳转 + " " + Config.PreLabel.Label + FunctionIndex + "_" + Name );
		return;
		
		
//		string LabelName = LabelList.GetLabelName( Name, Deploy.FunctionIndex );
//		if( LabelName == null ) {
//			ET.WriteParseError( Index, "未定义的标号: " + Name );
//			return;
//		}
//		Expression.AddIns( Code1.跳转 + " " + LabelName );
		
		//"f_goto_"
	}
	
	public static int VarLevel;		//变量层数
	public static int SenceNumber;	//程序中已经定义的控制语句数目
	public static int FunctionIndex;//当前函数的索引
	public static string UnitName;	//当前元件名
	public static int ChipIndex;	//当前的芯片索引
	public static int ExpLevel;		//表达式层,每次从表达式语句开始调用时初始化为0
}
}



